package com.moyuaninfo.enums;

import cn.hutool.core.util.XmlUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.moyuaninfo.utildatamodel.ResultData;
import com.moyuaninfo.utildatamodel.Returnsms;
import com.moyuaninfo.utils.AsciiUtils;
import com.moyuaninfo.utils.DetectionMessageUtils;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据报文的 Unit 数值与 Data 块的数据格式：（当前约定）
 * 注：当模块的 485 通讯失败时，所有的数据均为“NoLink”
 *
 * @author 邱祥霸
 * @version 1.0
 */
public enum UnitEnum {

    /** */
    UNIT_01("01", "Util_01.xml"){

        @Override
        public List<ResultData> due(String message) {
            // 获取数据模板
            List<Returnsms> dataModelList = DetectionMessageUtils.utilModelMap.get(this.getValue());

            // 获取报文数据
            String data = message.substring(18);
            return UnitEnum.getResultData(dataModelList, data);
        }
    }
    ,
    ;

    /** Util 的 HEX值 */
    private String value;

    /** 模板文件名*/
    private String dataModelName;

    /**
     * /** 处理报文 返回
     * @param message 报文
     * @return List<Returnsms> 数据值
     */
    abstract List<ResultData> due(String message);

    UnitEnum(String value, String dataModelName) {
        this.value = value;
        this.dataModelName = dataModelName;
    }

    /**
     * 处理报文
     * @param message 报文
     * @return List<Returnsms>
     */
    public static List<ResultData> dueMessage(String message) {
        try {
            // 获取util 值
            String unit = message.substring(12, 14);
            UnitEnum[] unitEnumArr = UnitEnum.values();
            for (UnitEnum unitEnum : unitEnumArr) {
                if (unitEnum.value.equals(unit)) {
                    return unitEnum.due(message);
                }
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析模板
     */
    public static void parseDataModel() {
        UnitEnum[] unitEnumArr = UnitEnum.values();
        for (UnitEnum unitEnum : unitEnumArr) {
            List<Returnsms> returnsmsList = new ArrayList<Returnsms>(64);

            // 获取模板路径
            URL url = UnitEnum.class.getClassLoader()
                    .getResource("com/moyuaninfo/utildatamodel/" + unitEnum.dataModelName);

            // 获取根节点
            Document docResult = XmlUtil.readXML(url.getPath());

            // 获取所有data节点
            List<Element> elementList =XmlUtil.getElements(docResult.getDocumentElement(), "data");

            // 解析xml为 Returnsms
            for (Element element : elementList) {
                String sequence = XmlUtil.getElement(element, "sequence").getTextContent();
                int index = Integer.parseInt(sequence.substring(4));

                Returnsms returnsms = Returnsms.builder()
                        .sequence(sequence)
                        .dataDescribe(XmlUtil.getElement(element, "dataDescribe").getTextContent())
                        .dataType(XmlUtil.getElement(element, "dataType").getTextContent())
                        .dataUtil(XmlUtil.getElement(element, "dataUtil").getTextContent())
                        .dataRemark(XmlUtil.getElement(element, "dataRemark").getTextContent())
                        .build();

                returnsmsList.add(returnsms);
            }

            DetectionMessageUtils.utilModelMap.put(unitEnum.value, returnsmsList);
        }

        System.out.println(DetectionMessageUtils.utilModelMap);
    }

    public String getValue() {
        return value;
    }

    /**
     * 解析报文数据
     * @param returnsmsList 模板
     * @param data 数据报文
     * @return List<ResultData>
     */
    private static List<ResultData> getResultData(List<Returnsms> returnsmsList, String data) {
        List<ResultData> resultDataList = new ArrayList<ResultData>();
        byte[] dataByte = data.getBytes();
        int dataByteLength = dataByte.length;
        int ij = 0;
        for (int i = 0; i < returnsmsList.size(); i ++) {
            // 数据取完
            if(ij + 12 > dataByteLength) {break;}

            // 获取数据模板
            Returnsms returnsms  =  returnsmsList.get(i);

            // 取模型对应的值
            byte[] byteArr = new byte[12];
            for (int a = 0; a < 12; a ++) {
                byteArr[a] = dataByte[ij++];
            }
            String dataValue = new String(byteArr);

            // 返回数据模型
            ResultData resultData = ResultData.builder()
                    .dataDescribe(returnsms.getDataDescribe())
                    .dataType(returnsms.getDataType())
                    .dataValue(AsciiUtils.hexToAscii(dataValue))
                    .dataUtil(returnsms.getDataUtil())
                    .build();

            resultDataList.add(resultData);
        }
        return resultDataList;
    }
}
